import logging
from controllers.errors.error import HTTPNotLoginError
from core.entities.account_role import AccountWrap
from extensions.ext_database import db
# from models.account import Account
from models.robot.intent_reco import RobFuncType, RobFuncs



class RobFuncService:
    @staticmethod
    def create_func(operator: AccountWrap, name: str, fun_type: str,  interaction_mode: str,agent_id:str|None=None, val_name: str | None = None, need_reconize: bool = False,price: int=0,descrip: str|None=None) -> RobFuncs|None:
        if not isinstance(operator, AccountWrap) or operator.current_tenant_id is None:
            raise HTTPNotLoginError()
        fun_type_enum = RobFuncType.from_code(fun_type)
        if fun_type_enum is None:
            raise ValueError("fun_type is invalid")
        if fun_type_enum == RobFuncType.AGENT:
            if not agent_id:
                raise Exception("agent_id is required for agent func_type")
        if interaction_mode.upper() not in ["I","B"]:
            raise Exception("interaction_mode is invalid")
        if interaction_mode.upper() == "I" and not val_name:
            raise Exception("value name is required")
        try:
            func = RobFuncs(
                name=name, # type:ignore
                descrip=descrip, # type:ignore
                fun_type=fun_type_enum.value, # type:ignore
                price=price, # type:ignore
                interaction_mode=interaction_mode,  # type:ignore
                inter_val_name=val_name if val_name else None, # type:ignore
                need_reconize=need_reconize, # type:ignore
                tenant_id=operator.current_tenant_id, # type:ignore
                created_by=operator.id, # type:ignore
            )
            if fun_type_enum == RobFuncType.AGENT:
                func.id = agent_id
            db.session.add(func)
            db.session.flush()
            return func
        except Exception as e:
            db.session.rollback()
            raise e

    @staticmethod
    def create_funcs(operator: AccountWrap, funcs: list[dict]) -> list[RobFuncs]:
        try:
            rets = []
            for func_args in funcs:
                func = RobFuncService.create_func(
                    operator=operator,
                    **func_args
                )
                rets.append(func)
            db.session.commit()
            return rets
        except Exception as e:
            db.session.rollback()
            raise e
        return []
    
    @staticmethod
    def get_funcs(tenant_id:str,name:str|None=None,fun_type:str|None=None,interaction_mode:str|None=None,need_reconize:bool|None=None,page:int=-1,page_size:int=-1)->dict:
        try:
            query = db.session.query(RobFuncs).filter(
                RobFuncs.tenant_id==tenant_id
            )
            if name:
                query = query.filter(RobFuncs.name.like(f"%{name}%"))
            if  fun_type:
                fun_ty = RobFuncType.from_code(fun_type)
                if fun_ty:
                    print(fun_ty.value)
                    query = query.filter(RobFuncs.fun_type==fun_ty.value)
            if interaction_mode:
                query = query.filter(RobFuncs.interaction_mode==interaction_mode)
            if need_reconize is not None:
                query = query.filter(RobFuncs.need_reconize==need_reconize)
            hasMore = False
            total = query.count()
            if page>0 and page_size>0:
                query = query.offset((page-1)*page_size).limit(page_size)
                hasMore = total>page_size*page
            funcs = query.all()
            return {
                "total":total,
                "hasMore":hasMore,
                "data":funcs,
            }
        except Exception as e:
            logging.error(e)
            return {
                "total":0,
                "hasMore":False,
                "data":[],
                "error":str(e),
            }
            